{
  "openapi": "3.0.0",
  "info": {
    "title": "TestingWebApp_Backend API",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "http://localhost:3000"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    }
  },
  "paths": {
    "/login": {
      "post": {
        "summary": "Вход пользователя и генерация токенов",
        "description": "Эта конечная точка аутентифицирует пользователей по их логину и паролю, генерируя токены доступа и обновления при успешной аутентификации.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "login",
                  "password",
                  "fingerprint"
                ],
                "properties": {
                  "login": {
                    "type": "string",
                    "description": "Логин пользователя"
                  },
                  "password": {
                    "type": "string",
                    "description": "Пароль пользователя"
                  },
                  "fingerprint": {
                    "type": "string",
                    "description": "Уникальный отпечаток устройства пользователя"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Успешный вход",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "access_token": {
                      "type": "string",
                      "description": "JWT токен доступа для авторизованного доступа к API"
                    },
                    "role": {
                      "type": "boolean",
                      "description": "Указывает, имеет ли пользователь права администратора (true) или нет (false)"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Неверный запрос - отсутствуют обязательные данные",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Недостаточно данных"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Не авторизован - неверные учетные данные",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Неверный логин или пароль"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Внутренняя ошибка сервера во время операции с базой данных",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Ошибка сервера"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/token": {
      "post": {
        "summary": "Обновление access-токена",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "refreshTokenId": {
                    "type": "string"
                  },
                  "fingerprint": {
                    "type": "string"
                  },
                  "account_id": {
                    "type": "integer"
                  }
                },
                "required": [
                  "refreshTokenId",
                  "fingerprint",
                  "account_id"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Access-токен обновлен",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "accessToken": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Недостаточно данных"
          },
          "401": {
            "description": "Неверный refresh-токен"
          },
          "500": {
            "description": "Ошибка сервера"
          }
        }
      }
    },
    "/logout": {
      "post": {
        "summary": "Выход пользователя и аннулирование токена обновления",
        "description": "Эта конечная точка позволяет пользователям выйти из системы и аннулирует их токен обновления, хранящийся в базе данных.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Успешный выход",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Успешно!"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Не авторизован - отсутствует или недействителен токен",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Требуется токен для выхода."
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Внутренняя ошибка сервера во время операции с базой данных",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Ошибка сервера"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/forgot-password": {
      "post": {
        "summary": "Запрос на восстановление пароля",
        "description": "Эта конечная точка позволяет пользователю запросить код подтверждения для восстановления пароля. Код отправляется на адрес электронной почты, связанный с указанным логином.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "login"
                ],
                "properties": {
                  "login": {
                    "type": "string",
                    "description": "Логин пользователя"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Запрос на восстановление пароля принят",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Код подтверждения отправлен на ваш адрес электронной почты"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Неверный запрос - отсутствует логин",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Требуется логин"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Внутренняя ошибка сервера (ошибка отправки email)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Ошибка сервера"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/verify-code": {
      "post": {
        "summary": "Проверка кода восстановления пароля",
        "description": "Эта конечная точка позволяет пользователю проверить код, полученный для восстановления пароля. Код сравнивается с сохраненным в сессии значением.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "code"
                ],
                "properties": {
                  "code": {
                    "type": "string",
                    "description": "Код подтверждения, полученный пользователем"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Код подтверждения верный",
            "content": {
              "application/json": {
                "schema": {
                  "type": "boolean",
                  "example": true
                }
              }
            }
          },
          "400": {
            "description": "Неверный запрос - отсутствует код или код не совпадает",
            "content": {
              "application/json": {
                "schema": {
                  "type": "boolean",
                  "example": false
                }
              }
            }
          }
        }
      }
    },
    "/reset-password": {
      "post": {
        "summary": "Сброс пароля пользователя",
        "description": "Эта конечная точка позволяет пользователю сбросить пароль после успешной проверки кода подтверждения. Новый пароль хешируется и сохраняется в базе данных.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "login",
                  "newPassword"
                ],
                "properties": {
                  "login": {
                    "type": "string",
                    "description": "Логин пользователя"
                  },
                  "newPassword": {
                    "type": "string",
                    "description": "Новый пароль пользователя"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Пароль успешно сброшен",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Пароль успешно сброшен"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Неверный запрос - отсутствуют данные или не пройдена проверка кода",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Отсутствуют обязательные поля"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Внутренняя ошибка сервера во время обновления базы данных",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Ошибка сервера"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/add-task": {
      "post": {
        "summary": "Добавление новой задачи",
        "description": "Эта конечная точка позволяет администратору добавить новую задачу с загрузкой файла в формате docx, pptx или doc. Требуется аутентификация и права администратора.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "material_title": {
                    "type": "string",
                    "description": "Название материала (задачи)"
                  },
                  "material_number": {
                    "type": "string",
                    "description": "Номер материала (задачи)"
                  },
                  "type_id": {
                    "type": "integer",
                    "description": "ID типа задачи (1 - лекция, 2 - практическая)"
                  },
                  "group_id": {
                    "type": "integer",
                    "description": "ID группы, для которой предназначена задача (1 - ИСП, 2 - ВЕБ)"
                  },
                  "DocxFile": {
                    "type": "string",
                    "format": "binary",
                    "description": "Файл задачи в формате docx, pptx или doc"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Задача успешно добавлена",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Задача успешно добавлена"
                    },
                    "task_id": {
                      "type": "integer",
                      "description": "ID добавленной задачи"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Неверный запрос - отсутствуют данные",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Отсутствуют необходимые данные"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Не авторизован - отсутствует или недействителен токен",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Требуется токен для аутентификации."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Доступ запрещен - недостаточно прав",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Неверный токен"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Внутренняя ошибка сервера",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Ошибка сервера"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/get-task": {
      "get": {
        "summary": "Получение файла задачи",
        "description": "Эта конечная точка позволяет аутентифицированным пользователям получить файл задачи в формате PDF по номеру и названию материала. Файл конвертируется в PDF, если он еще не существует в этом формате.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "material_number",
                  "material_title"
                ],
                "properties": {
                  "material_number": {
                    "type": "string",
                    "description": "Номер материала задачи"
                  },
                  "material_title": {
                    "type": "string",
                    "description": "Название материала задачи"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Файл задачи успешно получен",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "Неверный запрос - отсутствуют данные",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Недостаточно данных"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Не авторизован - отсутствует или недействителен токен",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Требуется токен для аутентификации."
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Внутренняя ошибка сервера",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Ошибка сервера"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/get-tasks": {
      "get": {
        "summary": "Получение списка задач",
        "description": "Эта конечная точка позволяет аутентифицированным пользователям получить список всех доступных задач из базы данных.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Список задач успешно получен",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "material_id": {
                        "type": "integer",
                        "description": "Уникальный идентификатор материала (задачи)"
                      },
                      "material_title": {
                        "type": "string",
                        "description": "Название материала (задачи)"
                      },
                      "type_id": {
                        "type": "integer",
                        "description": "ID типа задачи (1 - лекция, 2 - практическая)"
                      },
                      "group_id": {
                        "type": "integer",
                        "description": "ID группы, для которой предназначена задача (1 - ИСП, 2 - ВЕБ)"
                      },
                      "material_number": {
                        "type": "string",
                        "description": "Номер материала (задачи)"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Не авторизован - отсутствует или недействителен токен",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Требуется токен для аутентификации."
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Внутренняя ошибка сервера",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Ошибка сервера"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/update-task": {
      "put": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Обновление существующей задачи (только для администратора) НЕЗАКОНЧЕННОООО ПЕРЕДЕЛЫВААААТЬ!!!!!!!!!!!!",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "material_id": {
                    "type": "number"
                  },
                  "material_title": {
                    "type": "string"
                  },
                  "material_number": {
                    "type": "number"
                  },
                  "type_id": {
                    "type": "number"
                  },
                  "group_id": {
                    "type": "number"
                  }
                },
                "required": [
                  "material_id",
                  "material_title",
                  "material_number",
                  "type_id",
                  "group_id"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Задача успешно обновлена",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Недостаточно данных"
          },
          "500": {
            "description": "Ошибка сервера"
          }
        }
      }
    },
    "/delete-task": {
      "delete": {
        "summary": "Удаление задачи",
        "description": "Эта конечная точка позволяет администратору удалить задачу по номеру и названию материала. Требуется аутентификация и права администратора.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "material_number",
                  "material_title"
                ],
                "properties": {
                  "material_number": {
                    "type": "string",
                    "description": "Номер материала (задачи)"
                  },
                  "material_title": {
                    "type": "string",
                    "description": "Название материала (задачи)"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Задача успешно удалена",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Задача успешно удалена"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Неверный запрос - отсутствуют данные",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Отсутствуют необходимые данные"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Не авторизован - отсутствует или недействителен токен",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Требуется токен для аутентификации."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Доступ запрещен - недостаточно прав",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Неверный токен"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Внутренняя ошибка сервера",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Ошибка сервера"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/update-user": {
      "put": {
        "summary": "Обновление данных пользователя",
        "description": "Эта конечная точка позволяет администратору обновить логин и пароль пользователя. Требуется аутентификация и права администратора.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "login",
                  "password",
                  "account_id"
                ],
                "properties": {
                  "login": {
                    "type": "string",
                    "description": "Новый логин пользователя"
                  },
                  "password": {
                    "type": "string",
                    "description": "Новый пароль пользователя"
                  },
                  "account_id": {
                    "type": "integer",
                    "description": "ID пользователя, данные которого нужно обновить"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Данные пользователя успешно обновлены",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Успешно!"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Не авторизован - отсутствует или недействителен токен",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Требуется токен для аутентификации."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Доступ запрещен - недостаточно прав",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Неверный токен"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Внутренняя ошибка сервера во время обновления базы данных",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Ошибка сервера"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/get-user-data": {
      "get": {
        "summary": "Получение данных пользователя",
        "description": "Эта конечная точка позволяет аутентифицированным пользователям получить свои данные: для администратора - ФИО и логины всех остальных пользователей, для обычного пользователя - ID группы.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Данные пользователя успешно получены",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "fullname": {
                          "type": "string",
                          "description": "ФИО администратора"
                        },
                        "logins": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "description": "Логины остальных пользователей"
                          }
                        }
                      }
                    },
                    {
                      "type": "object",
                      "properties": {
                        "group_id": {
                          "type": "integer",
                          "description": "ID группы обычного пользователя"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Не авторизован - отсутствует или недействителен токен",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Требуется токен для аутентификации."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Пользователь не найден",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Пользователь не найден"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Внутренняя ошибка сервера",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Ошибка сервера"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}